/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.bo.OrderChangeShopWalletAmountBO;
import com.yami.shop.bean.enums.ShopWalletAmountType;
import com.yami.shop.bean.enums.ShopWalletChangeReason;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderRefund;
import com.yami.shop.bean.model.ShopWallet;
import com.yami.shop.bean.model.ShopWalletLog;
import com.yami.shop.bean.param.CustomerReqParam;
import com.yami.shop.bean.vo.ShopWalletVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.dao.ShopWalletLogMapper;
import com.yami.shop.dao.ShopWalletMapper;
import com.yami.shop.service.ShopWalletLogService;
import com.yami.shop.service.ShopWalletService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 商家钱包信息
 *
 * @author Dwl
 * @date 2019-09-19 14:02:57
 */
@Service
@AllArgsConstructor
public class ShopWalletServiceImpl extends ServiceImpl<ShopWalletMapper, ShopWallet> implements ShopWalletService {

    private final ShopWalletMapper shopWalletMapper;
    private final ShopWalletLogMapper shopWalletLogMapper;
    private final ShopWalletLogService shopWalletLogService;


    @Override
    public ShopWallet getShopWalletByShopId(Long shopId) {
        return shopWalletMapper.selectOne(new LambdaQueryWrapper<ShopWallet>().eq(ShopWallet::getShopId,shopId));
    }

    @Override
    public IPage<ShopWallet> pageShopWallet(PageParam<ShopWallet> page, ShopWallet shopWallet) {
        return shopWalletMapper.pageShopWallet(page, shopWallet);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAmountBySettledOrder(String orderNumber) {

        // 商家之所以会从一笔订单拿到钱，是因为确认收货 or 订单退款时有部分不退
        int count = shopWalletLogMapper.countInAmountByOrderNumber(orderNumber, ShopWalletChangeReason.SETTLED.value());
        // 幂等
        if (count > 0) {
            return;
        }

        List<ShopWalletLog> shopWalletLogs = shopWalletLogMapper.listByOrderNumber(orderNumber);

        // 商家需要结算的钱
        ShopWalletLog platformPayLog = null;
        ShopWalletLog shopPayLog = null;

        ShopWalletLog platformRefundLog = new ShopWalletLog();
        platformRefundLog.setUserAmount(0.0);
        platformRefundLog.setDistributionAmount(0.0);
        platformRefundLog.setPlatformAmount(0.0);
        platformRefundLog.setPlatformCommission(0.0);
        platformRefundLog.setChangeAomunt(0.0);
        ShopWalletLog shopRefundLog = new ShopWalletLog();
        shopRefundLog.setUserAmount(0.0);
        shopRefundLog.setDistributionAmount(0.0);
        shopRefundLog.setPlatformAmount(0.0);
        shopRefundLog.setPlatformCommission(0.0);
        shopRefundLog.setChangeAomunt(0.0);
        for (ShopWalletLog shopWalletLog : shopWalletLogs) {
            // 平台分账记录
            if (Objects.equals(shopWalletLog.getShopId(), Constant.PLATFORM_SHOP_ID)) {
                // 下单
                ShopWalletLog payLog = polymerizationShopWalletLog(platformRefundLog, shopWalletLog);
                if (payLog != null) {
                    platformPayLog = payLog;
                }
            }
            // 商家分账记录
            else {
                // 下单
                ShopWalletLog payLog = polymerizationShopWalletLog(shopRefundLog, shopWalletLog);
                if (payLog != null) {
                    shopPayLog = payLog;
                }
            }
        }
        // 保存店铺结算记录
        saveSettledLog(shopPayLog, shopRefundLog);

        // 保存平台结算记录
        saveSettledLog(platformPayLog, platformRefundLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAmountByOrder(List<Order> orders) {
        for (com.yami.shop.bean.model.Order order : orders) {
            // 商家之所以会从一笔订单拿到钱，是因为订单支付成功
            int count = shopWalletLogMapper.countInAmountByOrderId(order.getOrderNumber(), ShopWalletChangeReason.PAY.value());
            // 幂等
            if (count > 0) {
                return;
            }
            Date date = new Date();
            // 1. 商家应收 = 商品价格(包含运费) - 商家优惠 - 分销金额
            // 2. 商家应收 = 用户支付 + 平台补贴 - 分销金额
            // 商家实际待结算金额 = 用户支付 + 平台补贴 - 订单分销佣金 - 平台佣金
            double changeAmount =  Arith.add(order.getActualTotal(),order.getPlatformAmount());
            changeAmount = Arith.sub(Arith.sub(changeAmount,order.getDistributionAmount()),order.getPlatformCommission());

            // 商家添加未结算金额(因为添加了唯一索引，所以是不用怕多次加钱)
            shopWalletMapper.addUnsettledAmount(order.getShopId(), changeAmount);

            // 平台添加未结算金额（平台佣金 - 平台优惠分摊优惠金额）
            double platformChangeAmount = Arith.sub(order.getPlatformCommission(),order.getPlatformAmount());
            shopWalletMapper.addUnsettledAmount(Constant.PLATFORM_SHOP_ID, platformChangeAmount);

            ShopWalletLog shopWalletLog = new ShopWalletLog();

            shopWalletLog.setOrderNumber(order.getOrderNumber());
            shopWalletLog.setReason(ShopWalletChangeReason.PAY.value());
            shopWalletLog.setShopId(order.getShopId());
            shopWalletLog.setIoType(1);
            shopWalletLog.setChangeAomunt(changeAmount);
            shopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
            shopWalletLog.setUserAmount(order.getActualTotal());
            shopWalletLog.setDistributionAmount(order.getDistributionAmount());
            // 店铺补贴金额 = 总优惠金额 - 平台优惠金额
            shopWalletLog.setShopReduceAmount(Arith.sub(order.getReduceAmount(),order.getPlatformAmount()));
            shopWalletLog.setPlatformAmount(order.getPlatformAmount());
            shopWalletLog.setPlatformCommission(order.getPlatformCommission());
            shopWalletLog.setCreateTime(date);
            // 添加日志
            shopWalletLogMapper.insert(shopWalletLog);

            // 添加平台日志
            shopWalletLog.setShopId(Constant.PLATFORM_SHOP_ID);
            shopWalletLog.setIoType(platformChangeAmount >= 0 ? 1 : 0);
            shopWalletLog.setChangeAomunt(Math.abs(platformChangeAmount));
            shopWalletLogMapper.insert(shopWalletLog);

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settlementShopAmountByRefund(OrderChangeShopWalletAmountBO orderChangeShopWalletAmountBO) {

        // 看看这个订单有没有锁定过
        int count = shopWalletLogMapper.countOutAmountByRefundSn(orderChangeShopWalletAmountBO.getRefundSn(), ShopWalletChangeReason.SETTLED.value());
        double distributionAmount = Objects.isNull(orderChangeShopWalletAmountBO.getDistributionAmount()) ? 0.0 : orderChangeShopWalletAmountBO.getDistributionAmount();
        // 幂等
        if (count > 0) {
            return;
        }
        //    当前需要结算金额 = 用户实付金额 - 退款金额
        //    平台补贴改变量 = 平台补贴 * 当前需要结算金额 / 商品实际金额
        //    平台佣金改变量 = 平台佣金 * 当前需要结算金额 / 商品实际金额
        //    商家结算金额 =  当前需要结算金额 + 平台补贴改变量 - 平台佣金改变量
        //    平台结算金额 = 平台佣金改变量 - 平台补贴改变量
        double settlementAmount = orderChangeShopWalletAmountBO.getActualTotal() - orderChangeShopWalletAmountBO.getRefundAmount();
        // 平台补贴改变量
        double changePlatformAmount = orderChangeShopWalletAmountBO.getPlatformAllowanceAmount();
        // 平台佣金改变量
        double changePlatformCommission = Arith.sub(orderChangeShopWalletAmountBO.getPlatformCommission(),orderChangeShopWalletAmountBO.getChangePlatformCommission());
        // 商家结算金额 =  当前需要结算金额 + 平台补贴改变量 - 平台佣金改变量
        double shopSettlementAmount = Arith.sub(Arith.add(settlementAmount , changePlatformAmount),changePlatformCommission);
        ShopWalletLog shopWalletLog = new ShopWalletLog();
        shopWalletLog.setOrderNumber(orderChangeShopWalletAmountBO.getOrderNumber());
        shopWalletLog.setReason(ShopWalletChangeReason.SETTLED.value());
        shopWalletLog.setShopId(orderChangeShopWalletAmountBO.getShopId());


        // 结算的金额
        shopWalletLog.setUserAmount(settlementAmount);
        // 回退的分销金额
        shopWalletLog.setDistributionAmount(distributionAmount);
        // 回退的平台补贴
        shopWalletLog.setPlatformAmount(changePlatformAmount);
        // 回退的平台佣金
        shopWalletLog.setPlatformCommission(changePlatformCommission);
        // 商家改变金额
        shopWalletLog.setChangeAomunt(shopSettlementAmount);
        // 先减少[待结算支出]后增加[可用余额收入]
        shopWalletLog.setIoType(0);

        // 1. 订单部分退款导致订单关闭 商家结算操作,需要加上分销金额
        int successCount = shopWalletMapper.settledAmount(orderChangeShopWalletAmountBO.getShopId(), shopSettlementAmount);
        if (successCount < 1) {
            throw new YamiShopBindException("结算失败，无法进行退款");
        }

        shopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
        // 添加订单待结算金额的支出记录日志
        shopWalletLogMapper.insert(shopWalletLog);

        // 添加店铺可用余额的收入记录日志
        shopWalletLog.setIoType(1);
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLogMapper.insert(shopWalletLog);


        // 添加平台日志
        shopWalletLog.setShopId(Constant.PLATFORM_SHOP_ID);
        // 平台结算金额实际上改变金额 = 平台佣金改变量 - 平台补贴改变量
        double platformChangeAmount = Arith.sub(shopWalletLog.getPlatformCommission(),shopWalletLog.getPlatformAmount());
        shopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
        shopWalletLog.setIoType(platformChangeAmount >= 0 ? 0 : 1);
        shopWalletLog.setChangeAomunt(Math.abs(platformChangeAmount));
        // 添加订单待结算金额的支出记录日志
        shopWalletLogMapper.insert(shopWalletLog);

        // 添加平台可用余额的收入记录日志
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLog.setIoType(platformChangeAmount >= 0 ? 1 : 0);
        shopWalletLogMapper.insert(shopWalletLog);
        // 平台添加改变结算金额
        shopWalletMapper.settledAmount(Constant.PLATFORM_SHOP_ID, platformChangeAmount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundShopAmountByRefund(OrderChangeShopWalletAmountBO orderChangeShopWalletAmountBO) {

        // 看看这个订单有没有锁定过
        int count = shopWalletLogMapper.countOutAmountByRefundSn(orderChangeShopWalletAmountBO.getRefundSn(), ShopWalletChangeReason.ORDER_REFUND.value());
        // 幂等
        if (count > 0) {
            return;
        }
        // 先来记住几个公式：
        // 1. 商家应收 = 商品价格 - 商家优惠 - 分销金额
        // 2. 商家应收 = 用户支付 + 平台补贴 - 分销金额
        // 由于 如果优惠是按照比例来划分，那么用户选择退款金额占（订单/订单项）的比例应该是商家收入减少的比例
        // 可得两个公式：
        // 商家应收 = （商品价格 - 商家优惠 - 分销金额） *（1 - 退款金额 / 实付金额）
        // 商家应收 = （用户支付 + 平台补贴 - 分销金额） *（1 - 退款金额 / 实付金额）

        // 现规定，如果发生退款，则认为分销失效有：
        // 如果订单100元，分销10元，10元的分销费用由商家出，此时商家结算时，拿到90元。
        // 当用户进行退款，退1块的时候，分销会无效，此时商家拿回给出去的10元分销费用，并将1元给到退款用户，此时商家因为退款赚9元。 shopRealRefundAmount = -9
        // 当用户进行退款，退11块的时候，分销会无效，此时商家拿回给出去的10元分销费用，并将11元给到退款用户，此时商家因为11块退款仅亏1元。shopRealRefundAmount = 1

        // 有发生退款时：
        // 商家应收 = （商品价格 - 商家优惠） *（1 - 退款金额 / 实付金额）
        // 商家应收 = （实付金额 + 平台补贴） *（1 - 退款金额 / 实付金额）

        // 商家应退 = （实付金额 + 平台补贴） *（退款金额 / 实付金额）

        // 平台佣金应退 = 实付金额 *（退款金额 / 实付金额）

        // 商家改变金额 = 原商家应收（下单时商家应收） - 现在商家应收 - 平台佣金应退
        //             = （用户支付 + 平台补贴） - 分销金额 - （实付金额 + 平台补贴） - 平台佣金 *（退款金额 / 实付金额）
        //             = （用户支付 + 平台补贴）*（退款金额 / 实付金额） - 分销金额
        //             = （用户支付 + 平台补贴 - 平台佣金） * （退款金额 / 实付金额） - 分销金额
        //             = 退款金额 + （平台补贴 - 平台佣金）* （退款金额 / 实付金额） - 分销金额
        //             = 退款金额 + 平台补贴改变量 - 平台佣金改变量 - 分销金额

        // 平台补贴改变量
        // 平台佣金改变量
        // 商家改变金额 = 退款金额 + 平台补贴改变量 - 平台佣金改变量 -分销金额
        // 商品改变金额有以下两种情况
        //      70    =   100  +       10     -      10     -   20    （商家待结算金额-70）
        //     -10    =   10   +       10     -      10     -   20     （商家待结算金额+10）
        // 如果算出的商品改变金额为负数，负支出等于收入，就是说要把退款记录的收支类型改为收入才对
        double subAmount = Arith.add(orderChangeShopWalletAmountBO.getChangePlatformCommission() , orderChangeShopWalletAmountBO.getDistributionAmount());
        double shopRealRefundAmount = Arith.sub(Arith.add(orderChangeShopWalletAmountBO.getRefundAmount() , orderChangeShopWalletAmountBO.getPlatformAllowanceAmount()),subAmount);

        ShopWalletLog shopWalletLog = new ShopWalletLog();
        shopWalletLog.setRefundSn(orderChangeShopWalletAmountBO.getRefundSn());
        shopWalletLog.setOrderNumber(orderChangeShopWalletAmountBO.getOrderNumber());
        shopWalletLog.setReason(ShopWalletChangeReason.ORDER_REFUND.value());
        shopWalletLog.setShopId(orderChangeShopWalletAmountBO.getShopId());


        // 用户申请的退款金额
        shopWalletLog.setUserAmount(orderChangeShopWalletAmountBO.getRefundAmount());
        // 回退的分销金额
        shopWalletLog.setDistributionAmount(orderChangeShopWalletAmountBO.getDistributionAmount());
        // 回退的平台补贴
        shopWalletLog.setPlatformAmount(orderChangeShopWalletAmountBO.getPlatformAllowanceAmount());
        // 回退的平台佣金
        shopWalletLog.setPlatformCommission(orderChangeShopWalletAmountBO.getChangePlatformCommission());
        shopWalletLog.setShopReduceAmount(orderChangeShopWalletAmountBO.getShopReduceAmount());
        // 支出
        shopWalletLog.setIoType(0);
        // 商家改变金额
        if (shopRealRefundAmount >= 0) {
            shopWalletLog.setChangeAomunt(shopRealRefundAmount);
        } else {
            // 如果算出的商品改变金额为负数，负支出等于收入，就是说要把退款记录的收支类型改为收入
            shopWalletLog.setIoType(1);
            shopWalletLog.setChangeAomunt(Math.abs(shopRealRefundAmount));
        }


        // 1. 订单未确认收货则扣未结算金额
        // 2. 商家撤销拼团活动时失效拼团时，将待成团的队伍进行退款

        // 减少未结算金额
        int successCount = shopWalletMapper.subUnsettledAmount(orderChangeShopWalletAmountBO.getShopId(), shopRealRefundAmount);
        if (successCount < 1) {
            // 您的待结算金额不足，无法进行退款
            throw new YamiShopBindException("yami.not.sufficient.refund");
        }

        shopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
        // 添加日志
        shopWalletLogMapper.insert(shopWalletLog);

        // 添加平台日志
        shopWalletLog.setShopId(Constant.PLATFORM_SHOP_ID);
        // 平台实际上改变金额
        // 订单退款，补贴肯定是减少了，但是对于平台来说是赚钱了
        // 订单退款了，平台的佣金也是减少了，所以对于平台来说是亏钱的。
        double platformRealRefundAmount = Arith.sub(shopWalletLog.getPlatformAmount(),shopWalletLog.getPlatformCommission());
        shopWalletLog.setIoType(platformRealRefundAmount >= 0 ? 1 : 0);
        shopWalletLog.setChangeAomunt(Math.abs(platformRealRefundAmount));
        shopWalletLogMapper.insert(shopWalletLog);

        // 平台添加改变未结算金额
        shopWalletMapper.addUnsettledAmount(Constant.PLATFORM_SHOP_ID, platformRealRefundAmount);
    }

    @Override
    public ShopWallet getAllShop(CustomerReqParam customerReqParam) {
        ShopWallet shopWallet;
        if (Objects.nonNull(customerReqParam.getStartTime()) && Objects.nonNull(customerReqParam.getEndTime())) {
            shopWallet = shopWalletMapper.getShopByTime(customerReqParam.getShopName(), customerReqParam.getStartTime(), customerReqParam.getEndTime());
        } else {
            shopWallet = shopWalletMapper.getAllShop(customerReqParam.getShopName());
        }
        return shopWallet;
    }

    @Override
    public IPage<ShopWallet> pageShopWalletByTime(PageParam<ShopWallet> page, CustomerReqParam customerReqParam) {
        IPage<ShopWallet> shopWalletPage;
        if (Objects.nonNull(customerReqParam.getStartTime()) && Objects.nonNull(customerReqParam.getEndTime())) {
            shopWalletPage = shopWalletMapper.pageShopWalletByTime(page, customerReqParam.getShopName(), customerReqParam.getStartTime(), customerReqParam.getEndTime());
        } else {
            shopWalletPage = shopWalletMapper.pageAllShopWallet(page, customerReqParam.getShopName());
        }
        return shopWalletPage;
    }

    @Override
    public void addAmountByScoreOrder(Order order) {
        // 商家之所以会从一笔订单拿到钱，是因为订单支付成功
        int count = shopWalletLogMapper.countInAmountByOrderId(order.getOrderNumber(), ShopWalletChangeReason.PAY.value());
        // 幂等
        if (count > 0) {
            return;
        }
        Date date = new Date();
        // 平台添加结算金额（用户支付金额）
        shopWalletMapper.addSettledAmount(Constant.PLATFORM_SHOP_ID, order.getActualTotal());
        ShopWallet shopWallet = shopWalletMapper.selectOne(new LambdaQueryWrapper<ShopWallet>().eq(ShopWallet::getShopId, order.getShopId()));
        ShopWalletLog shopWalletLog = new ShopWalletLog();

        shopWalletLog.setOrderNumber(order.getOrderNumber());
        shopWalletLog.setReason(ShopWalletChangeReason.PAY.value());
        shopWalletLog.setShopId(order.getShopId());
        shopWalletLog.setIoType(1);
        shopWalletLog.setChangeAomunt(order.getActualTotal());
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLog.setUserAmount(order.getActualTotal());
        shopWalletLog.setDistributionAmount(0.00);
        // 店铺补贴金额 = 总优惠金额 - 平台优惠金额
        shopWalletLog.setShopReduceAmount(0.00);
        shopWalletLog.setPlatformAmount(order.getPlatformAmount());
        shopWalletLog.setPlatformCommission(0.00);
        shopWalletLog.setCreateTime(date);
        // 添加日志
        shopWalletLogMapper.insert(shopWalletLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleRefundError(OrderRefund orderRefund) {
        Long shopId = orderRefund.getShopId();
        ShopWalletLog shopWalletLog = shopWalletLogService.getOne(new LambdaQueryWrapper<ShopWalletLog>()
                .eq(ShopWalletLog::getRefundSn, orderRefund.getRefundSn())
                .eq(ShopWalletLog::getShopId, shopId)
                .eq(ShopWalletLog::getReason, ShopWalletChangeReason.ORDER_REFUND.value()));
        if (Objects.isNull(shopWalletLog)) {
            return;
        }
        ShopWalletLog platformWalletLog = shopWalletLogService.getOne(new LambdaQueryWrapper<ShopWalletLog>()
                .eq(ShopWalletLog::getRefundSn, orderRefund.getRefundSn())
                .eq(ShopWalletLog::getShopId, Constant.PLATFORM_SHOP_ID)
                .eq(ShopWalletLog::getReason, ShopWalletChangeReason.ORDER_REFUND.value()));
        //存在退款发放失败的记录，要增加商家的待结算金额
        ShopWalletLog newShopWalletLog = new ShopWalletLog();
        newShopWalletLog.setRefundSn(orderRefund.getRefundSn());
        newShopWalletLog.setOrderNumber(shopWalletLog.getOrderNumber());
        newShopWalletLog.setReason(ShopWalletChangeReason.REJECT_REFUND.value());
        newShopWalletLog.setShopId(shopId);
        //用户申请的退款金额
        newShopWalletLog.setUserAmount(shopWalletLog.getUserAmount());
        //分销金额
        newShopWalletLog.setDistributionAmount(shopWalletLog.getDistributionAmount());
        //平台补贴
        newShopWalletLog.setPlatformAmount(shopWalletLog.getPlatformAmount());
        //平台佣金
        newShopWalletLog.setPlatformCommission(shopWalletLog.getPlatformCommission());
        //改变金额
        newShopWalletLog.setChangeAomunt(shopWalletLog.getChangeAomunt());
        //收入
        newShopWalletLog.setIoType(1);
        //待结算金额
        newShopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
        //增加待结算金额
        shopWalletMapper.addUnsettledAmount(shopId, shopWalletLog.getChangeAomunt());
        //添加日志
        shopWalletLogMapper.insert(newShopWalletLog);

        //添加平台日志
        newShopWalletLog.setShopId(Constant.PLATFORM_SHOP_ID);
        newShopWalletLog.setIoType(Math.abs(platformWalletLog.getIoType() - 1));
        newShopWalletLog.setChangeAomunt(platformWalletLog.getChangeAomunt());
        shopWalletLogMapper.insert(newShopWalletLog);
        //平台减少待结算金额
        shopWalletMapper.subUnsettledAmount(Constant.PLATFORM_SHOP_ID, platformWalletLog.getChangeAomunt());
    }

    @Override
    public ShopWalletVO getShopWalletAndTransaction(Long shopId) {
        // 昨天的开始和结束时间
        Date startTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),-1));
        Date endTime = DateUtil.endOfDay(startTime);
        return shopWalletMapper.getShopWalletAndTransaction(shopId, startTime, endTime);
    }


    /**
     * 聚合订单支付退款导致商家金额变更的记录
     * @param refundWalletLog
     * @param shopWalletLog
     * @return
     */
    private ShopWalletLog polymerizationShopWalletLog(ShopWalletLog refundWalletLog, ShopWalletLog shopWalletLog) {
        if (Objects.equals(ShopWalletChangeReason.PAY.value(), shopWalletLog.getReason())) {
            return shopWalletLog;
        }
        // 退款
        else if (Objects.equals(ShopWalletChangeReason.ORDER_REFUND.value(), shopWalletLog.getReason())) {
            refundWalletLog.setUserAmount(Arith.add(refundWalletLog.getUserAmount(),shopWalletLog.getUserAmount()));
            refundWalletLog.setDistributionAmount(Arith.add(refundWalletLog.getDistributionAmount(),shopWalletLog.getDistributionAmount()));
            refundWalletLog.setPlatformAmount(Arith.add(refundWalletLog.getPlatformAmount(),shopWalletLog.getPlatformAmount()));
            refundWalletLog.setPlatformCommission(Arith.add(refundWalletLog.getPlatformCommission(),shopWalletLog.getPlatformCommission()));
            // 如果因为退款收入，实际上是减少了退款的钱
            double changeAmount = (shopWalletLog.getIoType() == 1) ? -shopWalletLog.getChangeAomunt() : shopWalletLog.getChangeAomunt();
            refundWalletLog.setChangeAomunt(Arith.add(refundWalletLog.getChangeAomunt(),changeAmount));
        }
        // 退款超时，拒绝退款
        else if (Objects.equals(ShopWalletChangeReason.REJECT_REFUND.value(), shopWalletLog.getReason())) {
            //要把退款金额减去
            refundWalletLog.setUserAmount(Arith.sub(refundWalletLog.getUserAmount(),shopWalletLog.getUserAmount()));
            refundWalletLog.setDistributionAmount(Arith.sub(refundWalletLog.getDistributionAmount(),shopWalletLog.getDistributionAmount()));
            refundWalletLog.setPlatformAmount(Arith.sub(refundWalletLog.getPlatformAmount(),shopWalletLog.getPlatformAmount()));
            refundWalletLog.setPlatformCommission(Arith.sub(refundWalletLog.getPlatformCommission(),shopWalletLog.getPlatformCommission()));
            refundWalletLog.setChangeAomunt(Arith.sub(refundWalletLog.getChangeAomunt(),shopWalletLog.getChangeAomunt()));
        }
        return null;
    }


    private void saveSettledLog(ShopWalletLog shopPayLog,ShopWalletLog shopRefundLog) {
        if (Objects.isNull(shopPayLog)) {
            return;
        }
        double changeAmount = shopPayLog.getChangeAomunt();
        ShopWalletLog shopWalletLog = new ShopWalletLog();
        shopWalletLog.setOrderNumber(shopPayLog.getOrderNumber());
        shopWalletLog.setReason(ShopWalletChangeReason.SETTLED.value());
        shopWalletLog.setShopId(shopPayLog.getShopId());
        int ioType = shopPayLog.getIoType();
        if(changeAmount - shopRefundLog.getChangeAomunt() < 0){
            ioType = 0;
        }
        // 如果之前未结算为负收入或者当前金额小于退款金额，则已结算的收入是负收入
        if(Objects.equals(ioType,0)){
            changeAmount = Arith.sub(-changeAmount,shopRefundLog.getChangeAomunt());
        }else{
            changeAmount = Arith.sub(changeAmount,shopRefundLog.getChangeAomunt());
        }
        shopWalletLog.setIoType(ioType);
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLog.setChangeAomunt(Math.abs(changeAmount));
        shopWalletLog.setUserAmount(Arith.sub(shopPayLog.getUserAmount(),shopRefundLog.getUserAmount()));
        shopWalletLog.setDistributionAmount(Arith.sub(shopPayLog.getDistributionAmount(),shopRefundLog.getDistributionAmount()));
        shopWalletLog.setPlatformAmount(Arith.sub(shopPayLog.getPlatformAmount(),shopRefundLog.getPlatformAmount()));
        shopWalletLog.setPlatformCommission(Arith.sub(shopPayLog.getPlatformCommission(),shopRefundLog.getPlatformCommission()));
        shopWalletLog.setCreateTime(new Date());
        // 插入订单结算待结算金额的支出记录
        insertUnsettleLog(shopPayLog, shopRefundLog, changeAmount, ioType);
        shopWalletLogMapper.insert(shopWalletLog);
        shopWalletMapper.settledAmount(shopWalletLog.getShopId(),changeAmount);
    }

    private void insertUnsettleLog(ShopWalletLog shopPayLog, ShopWalletLog shopRefundLog, double changeAmount, int ioType) {
        ShopWalletLog unSettleLog = new ShopWalletLog();
        unSettleLog.setOrderNumber(shopPayLog.getOrderNumber());
        unSettleLog.setReason(ShopWalletChangeReason.SETTLED.value());
        unSettleLog.setChangeAomunt(Math.abs(changeAmount));
        unSettleLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
        unSettleLog.setUserAmount(Arith.sub(shopPayLog.getUserAmount(), shopRefundLog.getUserAmount()));
        unSettleLog.setIoType(Math.abs(ioType - 1));
        unSettleLog.setDistributionAmount(Arith.sub(shopPayLog.getDistributionAmount(), shopRefundLog.getDistributionAmount()));
        unSettleLog.setShopId(shopPayLog.getShopId());
        unSettleLog.setPlatformAmount(Arith.sub(shopPayLog.getPlatformAmount(), shopRefundLog.getPlatformAmount()));
        unSettleLog.setPlatformCommission(Arith.sub(shopPayLog.getPlatformCommission(), shopRefundLog.getPlatformCommission()));
        unSettleLog.setCreateTime(new Date());
        shopWalletLogMapper.insert(unSettleLog);
    }
}
